package com.lagou.request;

import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Arrays;
import java.util.UUID;

public class RpcRequest implements Serializable {
    //请求id
    private String requestId;
    //类名
    private String className;
    //方法名
    private String methodName;
    //参数类型
    private Class<?>[] parameterTypes;
    //入参
    private Object[] parameters;
    //被代理的对象
    private Object delegate;
    //处理的结果
    private Object result;
    //结果类型
    private Class resultType;

    public Object getResult() {
        return result;
    }

    public void setResult(Object result) {
        this.result = result;
    }

    public Class getResultType() {
        return resultType;
    }

    public void setResultType(Class resultType) {
        this.resultType = resultType;
    }

    public Object getDelegate() {
        return delegate;
    }

    public void setDelegate(Object delegate) {
        this.delegate = delegate;
    }

    public String getRequestId() {
        return requestId;
    }

    public void setRequestId(String requestId) {
        this.requestId = requestId;
    }

    public String getClassName() {
        return className;
    }

    public void setClassName(String className) {
        this.className = className;
    }

    public String getMethodName() {
        return methodName;
    }

    public void setMethodName(String methodName) {
        this.methodName = methodName;
    }

    public Class<?>[] getParameterTypes() {
        return parameterTypes;
    }

    public void setParameterTypes(Class<?>[] parameterTypes) {
        this.parameterTypes = parameterTypes;
    }

    public Object[] getParameters() {
        return parameters;
    }

    public void setParameters(Object[] parameters) {
        this.parameters = parameters;
    }

    private RpcRequest(){

    }

    @Override
    public String toString() {
        return "RpcRequest{" +
                "requestId='" + requestId + '\'' +
                ", className='" + className + '\'' +
                ", methodName='" + methodName + '\'' +
                ", parameterTypes=" + Arrays.toString(parameterTypes) +
                ", parameters=" + Arrays.toString(parameters) +
                ", delegate=" + delegate +
                ", result=" + result +
                ", resultType=" + resultType +
                '}';
    }

    public static RpcRequest build(Class serviceClass, Method method, Object[] objects){
        RpcRequest request = new RpcRequest();
        request.requestId = UUID.randomUUID().toString().replaceAll("-","");
        request.className = serviceClass.getName();
        request.methodName = method.getName();
        if(objects != null){
            request.parameters = objects;
            request.parameterTypes = new Class[objects.length];
            for (int i = 0; i < objects.length; i++) {
                request.parameterTypes[i] = objects[i].getClass();
            }
        }
        //判断方法的返回类型是否为泛型类型，如果是泛型，需要取被包装的类型
        Type genericReturnType = method.getGenericReturnType();
        if (genericReturnType instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType)genericReturnType;
            Class finalType = (Class)parameterizedType.getActualTypeArguments()[0];
            request.setResultType(finalType);
        }else{
            request.setResultType(method.getReturnType());
        }
        return request;
    }

}

